#pragma once
#include "matrix.h"
#include "vector3.h"
#include "input.h"

using namespace krryn::math;

namespace krryn{
namespace view{
	class camera{
	public:
		virtual matrix view_matrix() const = 0;
	};

	class camera_fps : public camera{
	public:
		camera_fps() : m_Up(vector3f(0, 1, 0)), m_Target(vector3f(0, 0, 1)) {}
		// negative speed moves backwards
		void move(float a_Speed);
		void strafe(float a_Speed);
		void rotate(float a_Speed);

		virtual matrix view_matrix() const;
	private:
		math::vector3f m_Up, m_Target, m_Position;
	};

	class camera_fps_controller_default{
	public:
		camera_fps_controller_default(camera_fps *a_Camera, system::input_manager *a_InputManager) 
			: m_Camera(a_Camera), 
			  m_Mouse(a_InputManager->create_mouse_device()), 
			  m_Keyboard(a_InputManager->create_keyboard_device()),
			  m_LinearSpeed(40.f),
			  m_AngularSpeed(30.f) {}

		void update(float a_DeltaTime);
	private:
		float m_LinearSpeed, m_AngularSpeed;
		system::mouse *m_Mouse;
		system::keyboard *m_Keyboard;
		camera_fps *m_Camera;
	};

	//class camera{
	//public:
	//	camera(const math::vector3f &a_Up, const math::vector3f &a_Target, const math::vector3f &a_Pos)
	//		: m_Up(a_Up), m_Target(a_Target), m_Position(a_Pos) {}

	//	virtual void update(float a_DeltaTime) = 0;
	//	virtual void update_mouse(int a_SceenWidth, int a_SceenHeight) = 0;

	//	math::vector3f m_Up, m_Target, m_Position;
	//};

	//class camera_fps : public camera{
	//public:
	//	camera_fps(
	//		system::input *a_Input, const math::vector3f &a_Up, 
	//		const math::vector3f &a_Target, const math::vector3f &a_Pos);

	//	void update(float a_DeltaTime);
	//	void update_mouse(int a_SceenWidth, int a_SceenHeight);
	//private:
	//	system::input *m_Input;

	//	math::matrix get_look_at_matrix();

	//	 negative speed moves backwards
	//	void move(float a_Speed);
	//	void strafe(float a_Speed);
	//	void rotate(float a_Speed);
	//};
}
}
